package com.yuneec.fly.views;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.widget.RadioButton;
import android.widget.RadioGroup;

/**
 * Created by peng.gao on 2016/9/2.
 */
public class SmartWeightRadioGroup extends RadioGroup {
    public SmartWeightRadioGroup(Context context) {
        super(context);
        init();
    }

    public SmartWeightRadioGroup(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private RadioButton[] mRadioButtons = null;
    private float[] mRadioButtonWeight = null;
    private int mChildCount = 0;
    private Paint mRadioGroupOutlinePaint = new Paint();
    private Paint mRadioGroupDividerPaint = new Paint();
    private Paint mCheckedRadioButtonBackgroundPaint = new Paint();
    private int mCheckedIndex = 0;
    private int mLastCheckedIndex = 0;
    private static final String CHECKED_BUTTON_BACKGROUND_COLOR = "#279dd9";
    private static final float OUTLINE_WIDTH = 2;
    private static final float CORNER_RADIUS = 4;
    private AnimationValueBean mAnimationValueBean;
    private AnimationValueBean mLastAnimationValueBean;

    private void setCheckedIndex(int checkedIndex) {
        this.mLastCheckedIndex = this.mCheckedIndex;
        this.mCheckedIndex = checkedIndex;
        updateCheckedBackground();
    }

    private void init() {
        mRadioGroupOutlinePaint.setColor(Color.WHITE);
        mRadioGroupOutlinePaint.setStrokeWidth(OUTLINE_WIDTH);
        mRadioGroupOutlinePaint.setStyle(Paint.Style.STROKE);
        mRadioGroupOutlinePaint.setAntiAlias(true);
        mRadioGroupDividerPaint.setColor(Color.WHITE);
        mRadioGroupDividerPaint.setStrokeWidth(OUTLINE_WIDTH);
        mRadioGroupDividerPaint.setStyle(Paint.Style.FILL);
        mRadioGroupDividerPaint.setAntiAlias(true);
        mCheckedRadioButtonBackgroundPaint.setColor(Color.parseColor(CHECKED_BUTTON_BACKGROUND_COLOR));
        mCheckedRadioButtonBackgroundPaint.setStrokeWidth(OUTLINE_WIDTH);
        mCheckedRadioButtonBackgroundPaint.setStyle(Paint.Style.FILL);
        mCheckedRadioButtonBackgroundPaint.setAntiAlias(true);
        setOnCheckedChangeListener(null);
    }

    private void updateCheckedBackground() {
        if (mRadioButtons == null) {
            return;
        }
        RadioButton lastCheckedButton = mRadioButtons[mLastCheckedIndex];
        RadioButton checkedButton = mRadioButtons[mCheckedIndex];
        float[] lastRadius = new float[8];
        float[] checkedRadius = new float[8];
        for (int i = 0; i < checkedRadius.length; i++) {
            lastRadius[i] = 0;
            checkedRadius[i] = 0;
        }
        if (mLastCheckedIndex == 0) {
            lastRadius[0] = CORNER_RADIUS;
            lastRadius[1] = CORNER_RADIUS;
            lastRadius[6] = CORNER_RADIUS;
            lastRadius[7] = CORNER_RADIUS;
        }
        if (mLastCheckedIndex == mChildCount - 1) {
            lastRadius[2] = CORNER_RADIUS;
            lastRadius[3] = CORNER_RADIUS;
            lastRadius[4] = CORNER_RADIUS;
            lastRadius[5] = CORNER_RADIUS;
        }
        if (mCheckedIndex == 0) {
            checkedRadius[0] = CORNER_RADIUS;
            checkedRadius[1] = CORNER_RADIUS;
            checkedRadius[6] = CORNER_RADIUS;
            checkedRadius[7] = CORNER_RADIUS;
        }
        if (mCheckedIndex == mChildCount - 1) {
            checkedRadius[2] = CORNER_RADIUS;
            checkedRadius[3] = CORNER_RADIUS;
            checkedRadius[4] = CORNER_RADIUS;
            checkedRadius[5] = CORNER_RADIUS;
        }
        if (mLastCheckedIndex != mCheckedIndex || mLastAnimationValueBean == null) {
            mLastAnimationValueBean = new AnimationValueBean();
            mLastAnimationValueBean.radius = lastRadius;
            mLastAnimationValueBean.rectF = new RectF(lastCheckedButton.getX() + OUTLINE_WIDTH / 2,
                    lastCheckedButton.getY() + OUTLINE_WIDTH / 2,
                    lastCheckedButton.getX() + lastCheckedButton.getWidth() - OUTLINE_WIDTH / 2,
                    lastCheckedButton.getY() + lastCheckedButton.getHeight() - OUTLINE_WIDTH / 2);
        }
        mAnimationValueBean = new AnimationValueBean();
        mAnimationValueBean.radius = checkedRadius;
        mAnimationValueBean.rectF = new RectF(checkedButton.getX() + OUTLINE_WIDTH / 2,
                checkedButton.getY() + OUTLINE_WIDTH / 2,
                checkedButton.getX() + checkedButton.getWidth() - OUTLINE_WIDTH / 2,
                checkedButton.getY() + checkedButton.getHeight() - OUTLINE_WIDTH / 2);

        ValueAnimator valueAnimator = ValueAnimator.ofObject(new TypeEvaluator() {
            @Override
            public Object evaluate(float fraction, Object startValue, Object endValue) {
                AnimationValueBean startBean = (AnimationValueBean) startValue;
                AnimationValueBean endBean = (AnimationValueBean) endValue;
                float left = startBean.rectF.left + (endBean.rectF.left - startBean.rectF.left) * fraction;
                float top = startBean.rectF.top + (endBean.rectF.top - startBean.rectF.top) * fraction;
                float right = startBean.rectF.right + (endBean.rectF.right - startBean.rectF.right) * fraction;
                float bottom = startBean.rectF.bottom + (endBean.rectF.bottom - startBean.rectF.bottom) * fraction;
                float[] radius = new float[8];
                for (int i = 0; i < radius.length; i++) {
                    radius[i] = startBean.radius[i] + (int) ((endBean.radius[i] - startBean.radius[i]) * fraction);
                }
                AnimationValueBean animationValueBean = new AnimationValueBean();
                animationValueBean.rectF = new RectF(left, top, right, bottom);
                animationValueBean.radius = radius;
                return animationValueBean;
            }
        }, mLastAnimationValueBean, mAnimationValueBean);
        valueAnimator.setDuration(200);
        valueAnimator.setInterpolator(new AccelerateInterpolator(0.1f));
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mAnimationValueBean = (AnimationValueBean) animation.getAnimatedValue();
                postInvalidate();
            }
        });
        valueAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                mLastAnimationValueBean = mAnimationValueBean;
            }
        });
        valueAnimator.start();
    }


    @Override
    protected void dispatchDraw(Canvas canvas) {
        /*draw checked button background*/
        if (mAnimationValueBean == null) {
            updateCheckedBackground();
        } else {
            Path checkedPath = new Path();
            checkedPath.addRoundRect(mAnimationValueBean.rectF, mAnimationValueBean.radius, Path.Direction.CW);
            canvas.drawPath(checkedPath, mCheckedRadioButtonBackgroundPaint);
        }

         /*draw outline*/
        Path outlinePath = new Path();
        float[] outlineRadius = new float[8];
        for (int i = 0; i < outlineRadius.length; i++) {
            outlineRadius[i] = CORNER_RADIUS;
        }
        outlinePath.addRoundRect(new RectF(OUTLINE_WIDTH / 2, OUTLINE_WIDTH / 2, getWidth() - OUTLINE_WIDTH / 2, getHeight() - OUTLINE_WIDTH / 2), outlineRadius, Path.Direction.CW);
        canvas.drawPath(outlinePath, mRadioGroupOutlinePaint);
        super.dispatchDraw(canvas);
        for (int i = 0; i < mChildCount - 1; i++) {
            if (mRadioButtons[i].getVisibility() == GONE) {
                continue;
            }
            float startX = mRadioButtons[i].getX() + mRadioButtons[i].getWidth();
            float startY = mRadioButtons[i].getY();
            float stopX = startX;
            float stopY = startY + mRadioButtons[i].getHeight();
            Paint paint = new Paint();
            paint.setColor(Color.RED);
            paint.setStrokeWidth(2);
            canvas.drawLine(startX, startY, stopX, stopY, mRadioGroupDividerPaint);
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        if (mRadioButtons == null) {
            mChildCount = getChildCount();
            mRadioButtons = new RadioButton[mChildCount];
            mRadioButtonWeight = new float[mChildCount];
            int sumLength = 0;
            for (int i = 0; i < mChildCount; i++) {
                mRadioButtons[i] = (RadioButton) getChildAt(i);
                mRadioButtonWeight[i] = (float) Math.pow(1.1, mRadioButtons[i].getText().length());
                sumLength += mRadioButtonWeight[i];
            }
            for (int i = 0; i < mChildCount; i++) {
                RadioGroup.LayoutParams layoutParams = new LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT);
                layoutParams.weight = mRadioButtonWeight[i] / sumLength;
                mRadioButtons[i].setLayoutParams(layoutParams);
                if (mRadioButtons[i].isChecked()) {
                    mLastCheckedIndex = i;
                    mCheckedIndex = i;
                }
            }
        } else {
            for (int i = 0; i < mChildCount; i++) {
                if (mRadioButtons[i].isChecked()) {
                    setCheckedIndex(i);
                }
            }
        }
    }


    @Override
    public void setOnCheckedChangeListener(final OnCheckedChangeListener listener) {
        super.setOnCheckedChangeListener(new OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                for (int i = 0; i < mChildCount; i++) {
                    if (group.getChildAt(i).getId() == checkedId) {
                        setCheckedIndex(i);
                    }
                }
                if (listener != null) {
                    listener.onCheckedChanged(group, checkedId);
                }
            }
        });
    }

    private class AnimationValueBean {
        RectF rectF;
        float[] radius;
    }
}
